package com.caishi.lkx.user.login;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.caishi.lkx.common.config.DiamondConfig;
import com.caishi.lkx.common.util.Constants;
import com.caishi.lkx.common.util.SmsUtilService;
import com.caishi.lkx.common.yidun.WangyiYidunPlugins;
import com.caishi.lkx.user.dto.LoginDto;
import com.caishi.lkx.user.ienum.type.UserAccountType;
import com.caishi.lkx.user.ienum.type.UserChannelType;
import com.caishi.lkx.user.ienum.type.UserType;
import com.caishi.lkx.user.model.IUserModel;
import com.caishi.lkx.user.model.LoginInfoModel;
import com.caishi.lkx.user.model.MemberModel;
import com.caishi.lkx.user.service.IGroupService;
import com.caishi.lkx.user.service.ILoginInfoService;
import com.caishi.lkx.user.service.IMemberService;
import com.caishi.lkx.user.service.IUserService;
import com.caishi.lkx.user.service.impl.ConfigServiceImpl;
import com.zzw.common.exception.BizException;
import com.zzw.common.exception.BizRuntimeException;
import com.zzw.common.service.TypeServiceRouter;

import com.caishi.lkx.user.UserResultCode;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author by keray
 * date:2021/4/8 5:14 下午
 */
@Service("phoneLoginService")
class PhoneLoginServiceImpl implements LoginService {

    @Resource
    private DiamondConfig diamondConfig;

    @Resource
    private ILoginInfoService loginInfoService;

    @Resource
    private SmsUtilService smsUtilService;

    @Resource
    private IMemberService memberService;

    @Resource
    private ConfigServiceImpl configService;
    @Resource
    private WangyiYidunPlugins wangyiYidunPlugins;
    @Resource
    private IGroupService groupService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public LoginInfoModel loginBase(LoginDto loginDto, HttpServletRequest request, HttpServletResponse response) throws BizException {
        String phone = loginDto.getUserAccount();
        String code = loginDto.getCode();
        if(StrUtil.isNotBlank(loginDto.getToken())){
           Map obj =  groupService.getById(loginDto.getGroupId()).getConfig();
           JSONObject yidun = (JSONObject) obj.get(Constants.GROUP_CONFIG_YIDUN);
           phone = wangyiYidunPlugins.getMobileNumber(yidun.get(Constants.GROUP_CONFIG_YIDUN_BUSINESSID).toString(),loginDto.getToken(),loginDto.getAccessToken()).phone();
           if(StrUtil.isBlankIfStr(phone))
               throw new BizException(UserResultCode.phoneOneClickFail);
            loginDto.setUserAccount(phone);
            return doLogin(loginDto, request, response);
        }else{
            if (checkCode(phone, code)) {
                return doLogin(loginDto, request, response);
            }
            throw new BizException(UserResultCode.smsCodeError);
        }
    }

    @Override
    public LoginInfoModel doLogin(LoginDto loginDto, HttpServletRequest request, HttpServletResponse response) throws BizException {
        LoginInfoModel infoModel = loginInfoService.selectLoginInfoUserAccount(loginDto.getUserAccount(), loginDto.getType());
        var member = getDtoUserTypes(loginDto).stream().anyMatch(v -> v == UserType.member);
        var insert = infoModel == null && member;
        if (member && !insert) {
            try {
                checkLoginInfo(infoModel, loginDto);
                MemberModel memberModel = memberService.getById(infoModel.getUserId());
                if (null != memberModel) {
                    if (UserChannelType.carsi.equals(memberModel.getChannelType())) {
                        throw new BizRuntimeException(UserResultCode.casiLoginError);
                    }
                }
            } catch (BizException e) {
                if (e.getCode() == UserResultCode.loginInfoNotFound.getCode()) {
                    insert = true;
                } else throw e;
            }
        }
        // 用户自动注册
        if (insert) {
            var user = TypeServiceRouter.router(UserType.member).register(loginDto, request, response);
            if (null == loginInfoService.selectUserLoginInfo(user.getId(), UserAccountType.username) && null == loginInfoService.selectLoginInfoUserAccount(loginDto.getUserAccount(), UserAccountType.username)) {
                loginInfoService.userAddNewLogin(loginDto.getUserAccount(), diamondConfig.getUserDefaultPassword(), UserAccountType.username, user.getId());
            }
            infoModel = loginInfoService.selectUserLoginInfo(user.getId(), UserAccountType.phone);
            //memberService.sendVers6(user.getId(), user.getHeader(), true);
        }
        return checkLoginInfo(infoModel, loginDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public IUserModel<?> register(LoginInfoModel loginInfoModel, IUserModel<?> userModel) throws BizException {
        IUserService userService = TypeServiceRouter.router(UserType.int2Obj(userModel.getUserType()));
        var res = userService.register(userModel);
        loginInfoModel.setUserId(res.getId());
        return res;
    }


    public boolean checkCode(String phone, String code) {
        return smsUtilService.checkCode(phone, code, SmsUtilService.SmsCodeType.login);
    }
}
